/******************************************************************************
 * common/softirq.c
 * 
 * Softirqs in Xen are only executed in an outermost activation (e.g., never 
 * within an interrupt activation). This simplifies some things and generally 
 * seems a good thing.
 * 
 * Copyright (c) 2003, K A Fraser
 * Copyright (c) 1992, Linus Torvalds
 */

#include <xen/config.h>
#include <xen/init.h>
#include <xen/mm.h>
#include <xen/sched.h>
#include <xen/softirq.h>
#include <xen/sched-if.h>

#include <fs/fs.h>
#include <goldfish/audio.h>
#include <goldfish/goldfish.h>
#include <goldfish/card.h>
#include <goldfish/head.h>
#include <goldfish/goldfishfb.h>
#include <goldfish/drawchar.h>
#include <goldfish/fb.h>


#ifndef __ARCH_IRQ_STAT
irq_cpustat_t irq_stat[NR_CPUS];
#endif

static int flag = 0;
int sched_flag = 0;

static softirq_handler softirq_handlers[NR_SOFTIRQS];

asmlinkage irq_cpustat_t *get_irq_stat(void)
{
        return &irq_stat[smp_processor_id()];
}

extern void preuser(void);

void switch_init(void)
{
        unsigned int adr = (unsigned int)preuser;
        unsigned int temp;
        flag = 1;
        
         __asm__ __volatile__(
        "mrs    %0, cpsr    \n"
"       bic     %0, %0, #31\n"
"       orr     %0, %0, #16\n"
"       msr     spsr, %0\n"
"       movs    pc, %1"
        :
        : "r" (temp), "r" (adr)
        : "memory", "cc");
}

extern u8 _binary_24_bmp_start[];

u8* _binary_shut_wav_start;

void testsound(int *flag)
{
	static int offset=0;
    	static struct file fp;
	if(*flag == 61 && !goldfish_audio_fops.open(NULL,&fp))
		printk("open success\n");
	/*if(!goldfish_audio_fops.write(&fp,_binary_shut_wav_start+44+16380*offset++,16380,NULL))
	{
			offset--;
			(*flag)--;
	}*/
	if(!offset)
	{
		//printk("xxxxxxxxxxreadblkxxxxxxxxxxxxxxxxxxxxx\n");
		//readBlk(*flag- 60);
		offset = 0;
	}
	if(*flag == 61)	
		offset = 44;
	if(!goldfish_audio_fops.write(&fp,_binary_shut_wav_start+(offset==1?0:offset),31*512,NULL))
	{
			offset = 1;
			(*flag)--;
			return ;
	}
	offset = 0;
}

extern struct fb_image pic;
extern int flag_init;
void testfb()
{
        /*struct fb_image pic1 = {
                                        .dx = 0,
                                        .dy = 0,
                                        .width = goldfishfb->fb.var.xres,
                                        .height = goldfishfb->fb.var.yres,
                                        .depth = 16,
                                        .data = _binary_24_bmp_start + 54,
                                };
	pic.dx = pic.dy = 0;
	flag_init = 0;
        goldfishfb->fb.fbops->fb_imageblit(&goldfishfb->fb,&pic1);*/
	fresh_vmm_screen();
}

void testfb_dom()
{
	struct vcpu vcpu_tmp;
	unsigned long flags;
	struct domain* d = find_domain_by_domid(1);
	local_irq_save(flags);
	save_ptbase(&vcpu_tmp);
	write_ptbase(d->vcpu[0]);
	fresh_dom_screen();
	write_ptbase(&vcpu_tmp);
	local_irq_restore(flags);
}

void clearfb_dom()
{
	struct vcpu vcpu_tmp;
	unsigned long flags;
        struct domain* d = find_domain_by_domid(1);
        local_irq_save(flags);
        save_ptbase(&vcpu_tmp);
        write_ptbase(d->vcpu[0]);
	clear_dom_screen();	
        fresh_dom_screen();
        write_ptbase(&vcpu_tmp); 
        local_irq_restore(flags);
}

extern void __init mnt_init();
asmlinkage void do_softirq(void)
{
	unsigned int i, cpu = smp_processor_id();
	unsigned long pending;
	pending = softirq_pending(cpu);
	ASSERT(pending != 0);

	do {
		i = find_first_set_bit(pending);
		if(flag < 2 || sched_flag == 1)
		{
			if(flag == 0)
				switch_init();
			local_irq_enable();
			if(flag == 1){
				goldfish_pdev_bus_driver.probe(&goldfish_pdev_bus_device);
				printk("init screen\n");
				testfb();
				mnt_init();
			}
			flag = 2;
			sched_flag = 0;
			monitor();
		}
		clear_bit(i, &softirq_pending(cpu));
		(*softirq_handlers[i])();

		if(flag >=2 && flag <= 60)
			flag++;
		if(flag > 60)
		{
			flag++;
		}
	} while ( (pending = softirq_pending(cpu)) != 0 );
}

void open_softirq(int nr, softirq_handler handler)
{
	softirq_handlers[nr] = handler;
}

/*
 * Local variables:
 * mode: C
 * c-set-style: "BSD"
 * c-basic-offset: 4
 * tab-width: 4
 * indent-tabs-mode: nil
 * End:
 */
